// robot class
class Robot {
    // y
    i = 0;

    // x
    j = 0;

    current = null;

    // fuel
    fuel = 0;

    // size of the robot
    size = 0;

    // radius of the robot sight
    r = 0;

    constructor(current, fuel, size, r) {
        this.current = current;
        this.fuel = fuel;
        this.size = size;
        this.r = r;
    }

    // heuristic func for calculating priority of the cells
    heuristic(cellA, cellB, multiplier) {

        let dj = Math.abs(cellB.j - cellA.j);
        let di = Math.abs(cellB.i - cellA.i);
        return multiplier * (dj + di);
    }

    // func for checking if we found end
    isEnd(current, end) {
        return (current.i == end.i && current.j == end.j);
    }

    // A* alg
    aStar(start, end, robot) {

        // set of cells to be checked
        var open = new Array();

        // set of checked cells
        var closed = new Array();

        // path solution array
        var path = new Array();

        open.push(start);
        
        while(open.length !== 0) {

            let lowestIndex = 0;
            for (let i = 0; i < open.length; i++) {
                if (open[i].f < open[lowestIndex].f) {
                    lowestIndex = i;
                }
            }
            var current = open[lowestIndex];

            if (this.isEnd(current, end)) {
                var temp = current;
                //temp.isPath = true;
                path.push(temp);
                while (temp.parent) {
                    //temp.isPath = true;
                    path.push(temp.parent);
                    temp = temp.parent;
                }

                console.log("DONE!");
                // return the traced path
                return path.reverse();
            }

            open.splice(lowestIndex, 1);
            //current.isClosed = true;
            closed.push(current);

            var neighbors = current.edges;
            
            for (let i = 0; i < neighbors.length; i++) {                    
                var neighborEdge = neighbors[i];

                if (neighborEdge != null) {
                    var neighbor = neighborEdge.target;
                    if (!closed.includes(neighbor)) {
                        var possibleG = current.g + neighborEdge.weight;
                        
                        if (!open.includes(neighbor)) {
                            //neighbor.isOpen = true;
                            open.push(neighbor);            
                        } else if(possibleG >= neighbor.g) {
                            continue;
                        }   

                        neighbor.g = possibleG;
                        neighbor.h = this.heuristic(neighbor, end, 1)
                        neighbor.f = neighbor.g + neighbor.h + (neighborEdge.weight / (robot.fuel + neighbor.fuel));
                        neighbor.parent = current;
                    }                        
                }
            }
        }

        return [];
    }

    move(next) {
        report("Robot current fuel: " + this.fuel + "<br>");
        var e = this.current.edges;
        //report("current cell: " + e + "<br>");
        for (var i = 0; i < e.length; i++) {
            if (e[i] != null) {
                //report("edge " + i + " weight" + e[i].weight + "<br>");
                //report("target i=" + e[i].target.i + "; j=" + e[i].target.j + "<br>");
                if (e[i].target == next) {
                    report("Spend fuel: " + e[i].weight + "<br>");
                    this.fuel -= e[i].weight;
                    break;
                }
            }
        }
        this.current.isPath = true;
        this.current = next;
        this.current.parent = null;
        report("Robot new fuel: " + this.fuel + " + " + this.current.fuel + "<br>");
        this.fuel += this.current.fuel;
        if (this.fuel < 0) {
            return false;
        }
        return true;
    }

    openMap(cells) {
        var i = this.current.i;
        var j = this.current.j;

        var ii = i - this.r < 0 ? 0 : i - this.r;
        var jj = j - this.r < 0 ? 0 : j - this.r;
        var iii = i + this.r + 1 > cells.length ? cells.length : i + this.r + 1;
        var jjj = j + this.r + 1 > cells[0].length ? cells[0].length : j + this.r + 1;
        
        for (var i = ii; i < iii; i++) {
            for (var j = jj; j < jjj; j++) {
                cells[i][j].isVisible = true;
            }
        }
    }
}